package cn.jtfadmin.core.config.shiro;

import cn.jtfadmin.base.lang.common.domain.dto.ResultDTO;
import cn.jtfadmin.base.lang.common.utils.JsonUtils;
import cn.jtfadmin.base.shiro.config.ShiroCustomerFilter;
import cn.jtfadmin.base.shiro.statuscode.NoAuthorityStatusCodeConfig;
import cn.jtfadmin.core.constant.UrlConstant;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import javax.servlet.Filter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 系统认证filter
 */
@Component
public class SysAuthcFilter implements ShiroCustomerFilter {


    public final static String NAME = "sysAuthc";


    @Override
    public String getName() {
        return NAME;
    }

    @Override
    public Filter getFilter() {
        return new FormAuthenticationFilter() {
            protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
                HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
                httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
                response.getOutputStream().write(JsonUtils.toJsonStr(ResultDTO.error(NoAuthorityStatusCodeConfig.NO_AUTHORITY_CODE, "登录失效请重新登录"))
                        .getBytes(StandardCharsets.UTF_8));
            }

            @Override
            public String getLoginUrl() {
                return UrlConstant.SYS_LOGIN_URL;
            }

            protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
                                             ServletRequest request, ServletResponse response) throws Exception {
                return true;
            }

            protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e,
                                             ServletRequest request, ServletResponse response) {

                setFailureAttribute(request, e);
                //login failed, let request continue back to the login page:
                HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
                httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
                try {
                    if (e instanceof UnknownAccountException || e instanceof IncorrectCredentialsException) {
                        response.getOutputStream().write(JsonUtils.toJsonStr(ResultDTO.error(NoAuthorityStatusCodeConfig.USERNAME_OR_PWD_ERROR, "用户名或密码错误"))
                                .getBytes(StandardCharsets.UTF_8));
                        return false;
                    }
                    if (e instanceof DisabledAccountException) {
                        response.getOutputStream().write(JsonUtils.toJsonStr(ResultDTO.error(NoAuthorityStatusCodeConfig.USER_DISABLED, "用户被禁用"))
                                .getBytes(StandardCharsets.UTF_8));
                        return false;
                    }
                    response.getOutputStream().write(JsonUtils.toJsonStr(ResultDTO.error(NoAuthorityStatusCodeConfig.USERNAME_OR_PWD_ERROR, "用户名或密码错误"))
                            .getBytes(StandardCharsets.UTF_8));
                    return false;

                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                return false;
            }
        };
    }


}
